package com.bwton.msx.ccb.ui.auth;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;

import com.bwton.msx.ccb.databinding.FragmentFaceOpenBinding;
import com.bwton.msx.ccb.service.api.ApiServiceManager;
import com.bwton.msx.ccb.service.auth.AuthService;
import com.bwton.msx.ccb.service.user.UserManager;
import com.bwton.msx.ccb.ui.InteractiveActivity;
import com.bwton.msx.ccb.utils.FileUtil;
import com.bwton.msx.ccb.utils.RxViewUtils;
import com.bwton.msx.ccb.widget.dialog.PermissionDialog;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class FaceOpenFragment extends Fragment {
    private CompositeDisposable disposable = new CompositeDisposable();
    private FragmentFaceOpenBinding binding;
    private AuthService authService = new AuthService(ApiServiceManager.getAuth());
    private final String TAG = "人脸开通";
    private String face = "";
    private ActivityResultLauncher<Intent> faceRequestLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
        if (result.getResultCode() == Activity.RESULT_OK) {
            try {
                Intent data = result.getData();
                ArrayList<String> images = data.getStringArrayListExtra("image");
                Bitmap bitmap = BitmapFactory.decodeFile(images.get(1));
                binding.imageFace.setImageBitmap(bitmap);
                transformToBase64(images.get(1));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    private ActivityResultLauncher<String> cameraLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), permit -> {
        if (permit) {
            faceRequestLauncher.launch(new Intent(requireContext(), InteractiveActivity.class));
        }
    });

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {

        binding = FragmentFaceOpenBinding.inflate(inflater, container, false);
        return binding.getRoot();

    }

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        disposable = new CompositeDisposable();

        binding.btnRequestFace.setOnClickListener(v -> {
            checkPermission();
        });
        Disposable checkCache = Observable.create((ObservableOnSubscribe<String>) emitter -> {
                    File dir = FileUtil.mkDirs(String.format("%s/result/%s", requireContext().getCacheDir().getAbsolutePath(), "cache"),
                            "signImage");
                    File cache = new File(dir, "liveness.png");
                    if (cache.exists()) {
                        emitter.onNext(cache.getAbsolutePath());
                    }
                    emitter.onComplete();
                }).subscribeOn(Schedulers.io())
                .subscribe(cache -> {
                    Bitmap bitmap = BitmapFactory.decodeFile(cache);
                    binding.imageFace.setImageBitmap(bitmap);
                    transformToBase64(cache);
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                    }
                });
        disposable.add(checkCache);
        Disposable registerEvent = RxViewUtils.throttle(binding.btnSubmit, 5).subscribe(v -> {
            if (face.isEmpty()){
                Toast.makeText(requireContext(),"未找到人脸数据",Toast.LENGTH_SHORT).show();
                return;
            }
            Disposable openFace = authService.openFace(face)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(result->{
                        binding.textRequest.setText(result.toString());
                        if (result.success){
                            UserManager.getInstance().update(user->{
                                user.state.setEnableFace(true);
                                user.state.setFaceState("1");
                            });
                            NavHostFragment.findNavController(this).navigateUp();
                        }
                    }, new Consumer<Throwable>() {
                        @Override
                        public void accept(Throwable throwable) throws Exception {
                            throwable.printStackTrace();
                        }
                    });
            disposable.add(openFace);
        });
        disposable.add(registerEvent);
    }

    /**
     * 图片转base64
     * @param image
     */
    private void transformToBase64(String image) {
        try (FileInputStream fis = new FileInputStream(image);
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            face = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            if (ContextCompat.checkSelfPermission(
                    requireContext(),
                    Manifest.permission.CAMERA
            ) != PackageManager.PERMISSION_GRANTED) {
                displayCameraPermission();
            } else {
                faceRequestLauncher.launch(new Intent(requireContext(), InteractiveActivity.class));
            }

        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (requireContext().checkSelfPermission(Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                displayCameraPermission();
            } else {
                faceRequestLauncher.launch(new Intent(requireContext(), InteractiveActivity.class));
            }
        }
    }

    private void displayCameraPermission() {
        new PermissionDialog.Builder()
                .setContext(requireContext())
                .setOnClickListener(new PermissionDialog.OnClickListener() {
                    @Override
                    public void onCancelClick(PermissionDialog dialog) {
                        dialog.cancel();
                    }

                    @Override
                    public void onOkClick(PermissionDialog dialog) {
                        dialog.cancel();
                        cameraLauncher.launch(Manifest.permission.CAMERA);
                    }
                })
                .build().show();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
        disposable.dispose();
        disposable.clear();
    }

}